using CoreManager.Repository.Repositories;
using CoreManager.Models.DTOs;
using CoreManager.Models.Entities;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
using System.Linq.Expressions;
using CoreManager.API.Common;
using Microsoft.EntityFrameworkCore;
using System.Transactions;

namespace CoreManager.API.Controllers
{
    /// <summary>
    /// 用户管理控制器
    /// </summary>
    [ApiController]
    [Route("api/[controller]")]
    public class UsersController : BaseController
    {
        private readonly IRepository<User> _userRepository;
        private readonly IRepository<Role> _roleRepository;
        private readonly IRepository<UserRole> _userRoleRepository;
        private readonly ILogger<UsersController> _logger;

        public UsersController(
            IRepository<User> userRepository,
            IRepository<Role> roleRepository,
            IRepository<UserRole> userRoleRepository,
            ILogger<UsersController> logger) : base(logger)
        {
            _userRepository = userRepository;
            _roleRepository = roleRepository;
            _userRoleRepository = userRoleRepository;
            _logger = logger;
        }

        /// <summary>
        /// 获取用户列表
        /// </summary>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">页大小</param>
        /// <param name="userName">用户名</param>
        /// <param name="realName">真实姓名</param>
        /// <param name="email">邮箱</param>
        /// <param name="status">状态</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> GetUsers(
            int pageIndex = 1, 
            int pageSize = 20,
            string? userName = null,
            string? realName = null,
            string? email = null,
            int? status = null)
        {
            try
            {
                // 暂时使用简单查询，避免复杂条件表达式的SQL语法问题
                Expression<Func<User, bool>> queryExpression = u => true;

                var (users, total) = await _userRepository.GetPagedListAsync(
                    expression: queryExpression,
                    pageIndex: pageIndex,
                    pageSize: pageSize,
                    orderBy: u => u.CreateTime,
                    isAsc: false
                );

                var userDtos = users.Select(ConvertToDto).ToList();
                return PagedResult(userDtos, total, pageIndex, pageSize);
            }
            catch (Exception ex)
            {
                return HandleException(ex, "获取用户列表");
            }
        }

        /// <summary>
        /// 根据ID获取用户
        /// </summary>
        /// <param name="id">用户ID</param>
        /// <returns></returns>
        [HttpGet("{id}")]
        public async Task<IActionResult> GetUser(int id)
        {
            try
            {
                var user = await _userRepository.GetByIdAsync(id);
                if (user == null)
                {
                    return NotFound("用户不存在");
                }

                var userDto = ConvertToDto(user);
                return Success(userDto);
            }
            catch (Exception ex)
            {
                return HandleException(ex, $"获取用户失败，ID: {id}");
            }
        }

        /// <summary>
        /// 创建用户
        /// </summary>
        /// <param name="user">用户信息</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> CreateUser([FromBody] CreateUserDto user)
        {
            try
            {
                // 检查用户名是否已存在
                var existingUser = await _userRepository.GetAsync(u => u.UserName == user.UserName);
                if (existingUser != null)
                {
                    return BadRequest("用户名已存在");
                }

                // 检查邮箱是否已存在
                if (!string.IsNullOrEmpty(user.Email))
                {
                    var existingEmail = await _userRepository.GetAsync(u => u.Email == user.Email);
                    if (existingEmail != null)
                    {
                        return BadRequest("邮箱已存在");
                    }
                }

                var newUser = new User
                {
                    UserName = user.UserName,
                    Password = BCrypt.Net.BCrypt.HashPassword(user.Password),
                    RealName = user.RealName,
                    Email = user.Email,
                    Phone = user.Phone,
                    Status = user.Status,
                    Remark = user.Remark,
                    CreateUserId = GetCurrentUserId()
                };

                var userId = await _userRepository.InsertAsync(newUser);
                newUser.Id = userId;

                _logger.LogInformation($"用户创建成功，ID: {userId}");
                var userDto = ConvertToDto(newUser);
                return Success(userDto, "用户创建成功");
            }
            catch (Exception ex)
            {
                return HandleException(ex, "创建用户");
            }
        }

        /// <summary>
        /// 更新用户
        /// </summary>
        /// <param name="id">用户ID</param>
        /// <param name="user">用户信息</param>
        /// <returns></returns>
        [HttpPut("{id}")]
        public async Task<IActionResult> UpdateUser(int id, [FromBody] UpdateUserDto user)
        {
            try
            {
                var existingUser = await _userRepository.GetByIdAsync(id);
                if (existingUser == null)
                {
                    return NotFound("用户不存在");
                }

                // 检查邮箱是否被其他用户使用
                if (!string.IsNullOrEmpty(user.Email) && user.Email != existingUser.Email)
                {
                    var existingEmail = await _userRepository.GetAsync(u => u.Email == user.Email && u.Id != id);
                    if (existingEmail != null)
                    {
                        return BadRequest("邮箱已被其他用户使用");
                    }
                }

                existingUser.RealName = user.RealName;
                existingUser.Email = user.Email;
                existingUser.Phone = user.Phone;
                existingUser.Status = user.Status;
                existingUser.Remark = user.Remark;
                existingUser.UpdateUserId = GetCurrentUserId();

                await _userRepository.UpdateAsync(existingUser);

                _logger.LogInformation($"用户更新成功，ID: {id}");
                var userDto = ConvertToDto(existingUser);
                return Success(userDto, "用户更新成功");
            }
            catch (Exception ex)
            {
                return HandleException(ex, $"更新用户失败，ID: {id}");
            }
        }

        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="id">用户ID</param>
        /// <returns></returns>
        [HttpDelete("{id}")]
        public async Task<IActionResult> DeleteUser(int id)
        {
            try
            {
                var user = await _userRepository.GetByIdAsync(id);
                if (user == null)
                {
                    return NotFound("用户不存在");
                }

                // 不能删除自己
                var currentUserId = GetCurrentUserId();
                if (id == currentUserId)
                {
                    return BadRequest("不能删除自己");
                }

                await _userRepository.SoftDeleteAsync(id);

                _logger.LogInformation($"用户删除成功，ID: {id}");
                return Success("用户删除成功");
            }
            catch (Exception ex)
            {
                return HandleException(ex, $"删除用户失败，ID: {id}");
            }
        }

        /// <summary>
        /// 批量删除用户
        /// </summary>
        /// <param name="request">批量删除请求</param>
        /// <returns></returns>
        [HttpDelete("batch")]
        public async Task<IActionResult> BatchDeleteUsers([FromBody] BatchDeleteRequest request)
        {
            try
            {
                if (request.Ids == null || !request.Ids.Any())
                {
                    return BadRequest("请选择要删除的用户");
                }

                var currentUserId = GetCurrentUserId();
                if (request.Ids.Contains(currentUserId))
                {
                    return BadRequest("不能删除自己");
                }

                foreach (var id in request.Ids)
                {
                    await _userRepository.SoftDeleteAsync(id);
                }

                _logger.LogInformation($"批量删除用户成功，删除数量: {request.Ids.Count}");
                return Success($"成功删除 {request.Ids.Count} 个用户");
            }
            catch (Exception ex)
            {
                return HandleException(ex, "批量删除用户");
            }
        }

        /// <summary>
        /// 重置用户密码
        /// </summary>
        /// <param name="id">用户ID</param>
        /// <param name="request">重置密码请求</param>
        /// <returns></returns>
        [HttpPost("{id}/reset-password")]
        public async Task<IActionResult> ResetPassword(int id, [FromBody] ResetPasswordRequest request)
        {
            try
            {
                var user = await _userRepository.GetByIdAsync(id);
                if (user == null)
                {
                    return NotFound("用户不存在");
                }

                // 使用BCrypt加密新密码
                user.Password = BCrypt.Net.BCrypt.HashPassword(request.NewPassword);
                user.UpdateTime = DateTime.Now;
                user.UpdateUserId = GetCurrentUserId();

                await _userRepository.UpdateAsync(user);

                _logger.LogInformation($"重置用户密码成功，用户ID: {id}");
                return Success("密码重置成功");
            }
            catch (Exception ex)
            {
                return HandleException(ex, $"重置用户密码失败，用户ID: {id}");
            }
        }

        /// <summary>
        /// 切换用户状态
        /// </summary>
        /// <param name="id">用户ID</param>
        /// <param name="request">状态切换请求</param>
        /// <returns></returns>
        [HttpPost("{id}/toggle-status")]
        public async Task<IActionResult> ToggleUserStatus(int id, [FromBody] ToggleStatusRequest request)
        {
            try
            {
                var user = await _userRepository.GetByIdAsync(id);
                if (user == null)
                {
                    return NotFound("用户不存在");
                }

                // 不能禁用自己
                var currentUserId = GetCurrentUserId();
                if (id == currentUserId && request.Status == 0)
                {
                    return BadRequest("不能禁用自己");
                }

                user.Status = request.Status;
                user.UpdateTime = DateTime.Now;
                user.UpdateUserId = currentUserId;

                await _userRepository.UpdateAsync(user);

                var statusText = request.Status == 1 ? "启用" : "禁用";
                _logger.LogInformation($"{statusText}用户成功，用户ID: {id}");
                return Success($"用户{statusText}成功");
            }
            catch (Exception ex)
            {
                return HandleException(ex, $"切换用户状态失败，用户ID: {id}");
            }
        }

        /// <summary>
        /// 分配用户角色
        /// </summary>
        /// <param name="assignDto">用户角色分配DTO</param>
        /// <returns></returns>
        [HttpPost("assign-roles")]
        public async Task<IActionResult> AssignUserRoles([FromBody] AssignUserRolesDto assignDto)
        {
            using var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled);
            try
            {
                if (!ModelState.IsValid)
                {
                    return BadRequest("请求参数无效");
                }

                var user = await _userRepository.GetByIdAsync(assignDto.UserId);
                if (user == null)
                {
                    return NotFound("用户不存在");
                }

                // 验证角色是否存在
                if (assignDto.RoleIds.Any())
                {
                    var existingRoles = await _roleRepository.GetQueryable()
                        .Where(r => assignDto.RoleIds.Contains(r.Id) && !r.IsDeleted)
                        .ToListAsync();

                    if (existingRoles.Count != assignDto.RoleIds.Count)
                    {
                        return BadRequest("部分角色不存在");
                    }
                }

                // 获取用户所有的角色关联（包括软删除的）
                var allUserRoles = await _userRoleRepository.GetQueryable()
                    .Where(ur => ur.UserId == assignDto.UserId)
                    .ToListAsync();

                // 处理每个角色关联
                foreach (var userRole in allUserRoles)
                {
                    if (assignDto.RoleIds.Contains(userRole.RoleId))
                    {
                        // 如果新角色列表中包含此角色，确保它是激活状态
                        if (userRole.IsDeleted)
                        {
                            userRole.IsDeleted = false;
                            userRole.UpdateTime = DateTime.Now;
                            userRole.UpdateUserId = GetCurrentUserId();
                            await _userRoleRepository.UpdateAsync(userRole);
                        }
                    }
                    else
                    {
                        // 如果新角色列表中不包含此角色，软删除它
                        if (!userRole.IsDeleted)
                        {
                            await _userRoleRepository.SoftDeleteAsync(userRole.Id);
                        }
                    }
                }

                // 添加新的角色关联（只添加数据库中不存在的）
                var existingRoleIds = allUserRoles.Select(ur => ur.RoleId).ToList();
                var newRoleIds = assignDto.RoleIds.Where(roleId => !existingRoleIds.Contains(roleId)).ToList();

                foreach (var roleId in newRoleIds)
                {
                    var userRole = new UserRole
                    {
                        UserId = assignDto.UserId,
                        RoleId = roleId,
                        CreateUserId = GetCurrentUserId()
                    };

                    await _userRoleRepository.InsertAsync(userRole);
                }

                scope.Complete();
                _logger.LogInformation($"用户角色分配成功，用户ID: {assignDto.UserId}");
                return Success("用户角色分配成功");
            }
            catch (Exception ex)
            {
                return HandleException(ex, $"分配用户角色失败，用户ID: {assignDto.UserId}");
            }
        }

        /// <summary>
        /// 获取用户的角色列表
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <returns></returns>
        [HttpGet("{userId}/roles")]
        public async Task<IActionResult> GetUserRoles(int userId)
        {
            try
            {
                var user = await _userRepository.GetByIdAsync(userId);
                if (user == null)
                {
                    return NotFound("用户不存在");
                }

                var userRoles = await _userRoleRepository.GetQueryable()
                    .Where(ur => ur.UserId == userId && !ur.IsDeleted)
                    .Join(_roleRepository.GetQueryable().Where(r => !r.IsDeleted),
                        ur => ur.RoleId,
                        r => r.Id,
                        (ur, r) => new RoleDto
                        {
                            Id = r.Id,
                            RoleName = r.RoleName,
                            RoleCode = r.RoleCode,
                            Sort = r.Sort,
                            Status = r.Status,
                            Remark = r.Remark,
                            CreateTime = r.CreateTime,
                            UpdateTime = r.UpdateTime
                        })
                    .ToListAsync();

                return Success(userRoles);
            }
            catch (Exception ex)
            {
                return HandleException(ex, $"获取用户角色失败，用户ID: {userId}");
            }
        }


        /// <summary>
        /// 转换User实体为UserDto
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        private UserDto ConvertToDto(User user)
        {
            return new UserDto
            {
                Id = user.Id,
                UserName = user.UserName,
                RealName = user.RealName,
                Email = user.Email,
                Phone = user.Phone,
                Avatar = user.Avatar,
                Status = user.Status,
                LastLoginTime = user.LastLoginTime?.ToString("yyyy-MM-dd HH:mm:ss"),
                LastLoginIp = user.LastLoginIp,
                Remark = user.Remark,
                CreateTime = user.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"),
                UpdateTime = user.UpdateTime?.ToString("yyyy-MM-dd HH:mm:ss"),
                RoleIds = new List<int>(), // 将在需要时异步加载
                Roles = new List<RoleDto>()
            };
        }

        /// <summary>
        /// 转换User实体为UserDto（包含角色信息）
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        private async Task<UserDto> ConvertToDtoWithRoles(User user)
        {
            var userDto = ConvertToDto(user);
            
            // 获取用户角色信息
            var userRoles = await _userRoleRepository.GetQueryable()
                .Where(ur => ur.UserId == user.Id && !ur.IsDeleted)
                .Join(_roleRepository.GetQueryable().Where(r => !r.IsDeleted),
                    ur => ur.RoleId,
                    r => r.Id,
                    (ur, r) => new RoleDto
                    {
                        Id = r.Id,
                        RoleName = r.RoleName,
                        RoleCode = r.RoleCode,
                        Sort = r.Sort,
                        Status = r.Status,
                        Remark = r.Remark,
                        CreateTime = r.CreateTime,
                        UpdateTime = r.UpdateTime
                    })
                .ToListAsync();

            userDto.Roles = userRoles;
            userDto.RoleIds = userRoles.Select(r => r.Id).ToList();
            
            return userDto;
        }
    }
}